V. 8分钟搞懂面向对象编程 面向过程vs面向对象 OOP 封装 继承 多态_哔哩哔哩_bilibili
8分钟搞懂面向对象编程 | 面向过程vs面向对象 | OOP | 封装 继承 多态_哔哩哔哩_bilibili
新手在学习编程的路上,一个躲不过的坎就是面向对象编程,也叫 OOP,它当然不是你让你对象坐你对面写代码就算面向对象编程了,但要完全理解他.难度不见得比找一对象低
温馨提示,本视频目的是帮你理解 OOP 概念.不涉及讲解具体的 OOP 代码,仅用 Python 做简单示范,语法讲解,请听下回分解.
面向对象一般会和面向过程对比,接触 OOP 之前,我们基本上都是在面向过程编程.过程是负责完成某个具体任务的代码,基本可以理解为函数. 面向过程编程的核心,就是把要实现的事情拆分成一个个步骤依次完成,比如我们写个 ATM 的程序.要往里面依次存入 50 块和取出 100 块,那就按照顺序写出这些步骤,并配合定义出存钱和取钱的函数.假如我们还需要记录存钱和取钱是哪个 ATM 机执行的,ATM 属于哪个银行,以及纸币的编号.那就可以把这些作为参数补充上去,这种写法没什么毛病,但如果还要记录更多性质.比如 ATM 所属支行,纸币发行年份等这些散落的数据,一方面会增加函数参数的数量.另一方面,ATM 有编号,纸币也有编号,这些数据在传参过程中混在一起.并不利于我们理解其具体含义,随着程序长度和逻辑复杂度的增加,代码的清晰度可能由此降低.但如果我们用面向对象变成呢,正如名字所言,相比过程,它以对象为核心.面向对象编程首先并不会聚焦于第一步是去存钱还是取钱,而是模拟真实世界.
先考虑各个对象有什么性质,能做什么事情.比如每个 ATM 都有自己的性质.包括编号,银行,支行,那么我们可以提取出这些性质,定义 ATM 类.然后用类创建对象,类和对象之间的关系是类是创建对象的模板.对象是类的实例,更通俗点说,可以把类想象成制造具体对象的图纸.图纸上说 ATM 可以有编号,银行,支行这三个属性,那么通过 ATM 类创建出来的 ATM 实例.无论是招商银行南苑支行编号 001 的 ATM1,还是中国银行北苑支行编号 002 位的 ATM2.都是 ATM 对象,这些编号,银行,支行则是不同 ATM 对象各自的属性.我们可以用相同的方式,把纸币类以及通过纸币类创建的两个纸币对象也定义出来.现在这些对象就可以直接作为参数传入存钱和取钱函数中,你可能会说,且慢,虽然现在参数是少了.但多了两大坨定义类的代码,这不是得不偿失吗?面向对象除了能让参数更少之外.用对象把相关属性绑定在一起还有利于让程序逻辑更加清晰,比如虽然 ATM 和纸币都有编号.但我们用 ATM1.编号获取属于 ATM1 的编号,用纸币 1.编号获取纸币 1 的编号.这能让人更加清楚性质所属的对象是什么,以及假如我们存取钱的时候还要打印记录.如果不用对象,那得把那一大堆信息参数传递过去,但有了对象后.就可以直接通过对象来获取与他绑定的属性,相比带着一大堆数据到处传.
这会让逻辑以及数据的后续流动更加清晰,除了属性之外,另一个能和对象绑定的是方法.正如真实世界里对象拥有不同的属性并且能做不同的事情,那属性就对应对象拥有的性质.而方法对应对象能做些什么. 还是以我们熟悉的面向过程编程先作为例子.如果要执行洗衣服的任务,我们就按顺序写出这些步骤,并配合定义出放,开机,清洗,烘干等函数.可以看到,面向过程编程就像说明书一样一步步指导执行各个步骤,而面向对象编程呢.在这里面,人,洗衣机,都是执行事物的对象,人能放东西和开机.洗衣机能清洗和烘干,所以这些可以作为类的方法被定义出来,换个角度来看.所谓方法就是放在类里面的函数,所谓属性就是放在类里面的变量,定义好类之后.就可以通过类来创建对象,然后让各个对象去执行这些方法,相比面向过程编程直接聚焦于按步骤执行.面向对象编程把事物先分解到对象身上,描述各个对象的作用,然后才是他们之间的交互.就正如知乎上有个答案说,面向过程是编年体,面向对象是纪传体,而且.对象不仅可以把所有相关属性和方法绑在一起,结合方法和属性还能够更优雅的处理复杂逻辑.比如如果洗衣机的方法需要用到容量这个信息,那容量其实可以作为属性.在对象被创建的时候就进行设置,后面不管是哪个方法,需要用到容量,这个信息都不需要作为参数再被传入.而是作为自身属性可以直接被获取到,通过这些例子,我们应该多少能感受到,在逻辑或信息复杂的时候,面向对象编程可以让逻辑更清晰,信息更集中.除了这些好处之外,面向对象还有三个被反复提及的特性,封装继承多态.这三个词吧,虽然字都认得组合起来啥意思却并不直观,但没关系,我们一个个看.
封装表示写类的人将内部实现细节隐藏起来,使用类的人只通过外部接口访问和使用.接口可以被大致理解为提供使用的方法,比如如果有人已经写好了洗衣机这个类.你其实只需要知道它有什么方法,方法有什么作用,具体怎么用就足够了,不需要知道方法里面具体是怎么写的.这和真实世界是一样的,我们现实中使用洗衣机时,也是直接通过操作界面的按钮来使用.不需要知道里面的原理,也不需要钻到洗衣机背后研究电路板,封装能减少我们对不必要细节的精力投入.
继承是在说面向对象编程允许创建有层次的类,就像现实中的儿子继承爸爸.爸爸继承爷爷,类也可以有字类和父类来表示从属关系,比如小学生大学生都是学生.都应该有学号,年级的属性,都要去学校,可以看到这两个类之间的共同之处.导致有很多重复代码产生,但我们可以创建出一个叫学生的父类,然后让小学生和大学生去继承这个类.这样做的好处是,父类的那些属性方法都可以被继承,不需要反复定义.减少代码的冗余
多态指的是同样的接口因为对象具体类的不同而有不同表现.比如虽然小学生和大学生都要写作业,但内容的难度肯定不一样,所以这个写作业的方法就不能直接定义在父类里面,而是要分别定义在子类里,否则大学生和小学生用的就是同一个方法.那假如作为俩孩子的家长,家里正好一个大学生一个小学生,你要这俩对象写作业的时候.其实不用管具体写的是高难度还是低难度作业都可以一视同仁调用写作业方法.而他们会由于所属类不同执行不同的写作业方法,这就是多态,可以想象下.如果不用类的话还得用 if,先去判断崽子的类型,然后手动调用不同的写作业函数.面向对象编程的多态,让你可以无需判断统一调用同一名称的方法.但这也不是说面向对象就一定优于面向过程,如果他全方位碾压面向过程.那面向过程也不会成为另一个主流了,只能说选择哪个,还是取决于具体场景具体需求.当然了,如果你用的是 c 这种纯面向过程语言,或 Java 这种纯面向对象语言,那咱也不需要花时间纠结了.那现在你应该对面向对象这个不是那么容易理解的概念有了更深的认知.如果还不理解,那就收藏一步,回头多看几遍就理解了,我们下个声音,拜拜.